package cn.jninber.readmobile.client

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Xml
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import cn.jninber.lib.filemanager.ChooserManager
import cn.jninber.lib.filemanager.FileType
import com.kaopiz.kprogresshud.KProgressHUD
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import jxl.Workbook.getWorkbook
import kotlinx.android.synthetic.main.activity_main.*
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import timber.log.Timber
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.util.*
import java.util.regex.Pattern
import java.util.zip.ZipException
import java.util.zip.ZipFile

class MainActivity : AppCompatActivity() {


    lateinit var pro: KProgressHUD

    var data = LinkedList<String>();

    var isformat = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        pro = KProgressHUD(this)
                .setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
                .setLabel("Please wait")
                .setCancellable(true)
        Timber.asTree()
        mBtnSearch.setOnClickListener {
            val fileFragment = ChooserManager.Builder()
                    .withFileFilter(mutableListOf(FileType.EXCEL))
                    .withShowHideFinder(false)
                    .setOnFileSelectListener {
                        mTextPath.text = it
                        var path = it
                        data.clear()
                        Observable.create<LinkedList<String>> { sub ->
                            sub.onNext(if (path.toLowerCase().endsWith("xlsx")) readXlsx(path) else readXls(path))
                            sub.onComplete()
                        }.subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe(object : Observer<LinkedList<String>> {
                                    override fun onError(e: Throwable?) {
                                    }

                                    override fun onComplete() {
                                        pro.dismiss()
                                    }

                                    override fun onSubscribe(d: Disposable?) {
                                        pro.show()
                                    }

                                    override fun onNext(t: LinkedList<String>) {
                                        data.addAll(t)
                                        val mobile = StringBuffer()
                                        mobile.append("总共${data.size}条记录").append("\n")
                                        data.sort()
                                        for (i in 0..data.size - 1) {
                                            mobile.append(data[i]).append("\n")
                                            if (i != 0 && (i + 1) % ITEMLENGTH == 0) {
                                                mobile.append("======分割线======").append("\n")
                                            }
                                        }
                                        isformat = false
                                        if (data.size > 0) {
                                            isNeedeGroup = true
                                            invalidateOptionsMenu()
                                        }
                                        mobile_text.text = mobile.toString()

                                    }

                                })
                        runOnUiThread({
                            readXls(it)
                        })
                    }.build()

            fileFragment.show(supportFragmentManager, null)

        }
    }


    private fun readXls(xlsName: String): LinkedList<String> {
        val countryList = LinkedList<String>()
        try {
            val workbook = getWorkbook(FileInputStream(xlsName))
            workbook.sheets.forEach {
                val sheet = it
                val sheetRows = sheet.rows
                val sheetColumns = sheet.columns
                for (row in 0 until sheetRows) {
                    for (col in 0 until sheetColumns) {
                        val cell = sheet.getCell(col, row)
                        if (cell.contents?.checkMobile() == true) {
                            countryList.add(cell.contents)
                        }
                    }
                }
            }
            workbook.close()
        } catch (e: Exception) {
            Timber.d("read error=" + e, e)
        }
        return countryList
    }


    fun readXlsx(path: String): LinkedList<String> {
        var str: String? = ""
        var v: String? = null
        var flat = false
        val ls = ArrayList<String>()
        val countryList = LinkedList<String>()
        try {
            val xlsxFile = ZipFile(File(path))
            val sharedStringXML = xlsxFile
                    .getEntry("xl/sharedStrings.xml")
            val inputStream = xlsxFile.getInputStream(sharedStringXML)
            val xmlParser = Xml.newPullParser()
            xmlParser.setInput(inputStream, "utf-8")
            var evtType = xmlParser.eventType
            while (evtType != XmlPullParser.END_DOCUMENT) {
                when (evtType) {
                    XmlPullParser.START_TAG -> {
                        val tag = xmlParser.name
                        if (tag.equals("t", ignoreCase = true)) {
                            ls.add(xmlParser.nextText())
                        }
                    }
                    XmlPullParser.END_TAG -> {
                    }
                    else -> {
                    }
                }
                evtType = xmlParser.next()
            }
            val sheetXML = xlsxFile.getEntry("xl/worksheets/sheet1.xml")
            val inputStreamsheet = xlsxFile.getInputStream(sheetXML)
            val xmlParsersheet = Xml.newPullParser()
            xmlParsersheet.setInput(inputStreamsheet, "utf-8")
            var evtTypesheet = xmlParsersheet.eventType
            while (evtTypesheet != XmlPullParser.END_DOCUMENT) {
                when (evtTypesheet) {
                    XmlPullParser.START_TAG -> {
                        val tag = xmlParsersheet.name
                        if (tag.equals("row", ignoreCase = true)) {
                        } else if (tag.equals("c", ignoreCase = true)) {
                            val t = xmlParsersheet.getAttributeValue(null, "t")
                            if (t != null) {
                                flat = true
                                println(flat.toString() + "有")
                            } else {
                                println(flat.toString() + "没有")
                                flat = false
                            }
                        } else if (tag.equals("v", ignoreCase = true)) {
                            v = xmlParsersheet.nextText()
                            if (v != null) {
                                if (flat) {
                                    str += ls[Integer.parseInt(v)] + "  "
                                    if (ls[Integer.parseInt(v)].checkMobile()) {
                                        countryList.add(ls[Integer.parseInt(v)])
                                    }
                                } else {
                                    str += v + "  "
                                }
                            }
                        }
                    }
                    XmlPullParser.END_TAG -> if (xmlParsersheet.name.equals("row", ignoreCase = true) && v != null) {
                        str += "\n"
                    }
                }
                evtTypesheet = xmlParsersheet.next()
            }
            Timber.d(str)
        } catch (e: ZipException) {
            Toast.makeText(this, "解压文件失败,请确认时候为xlxs格式", Toast.LENGTH_SHORT).show()
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
            Toast.makeText(this, "读取文件失败,请确认时候为xlxs格式", Toast.LENGTH_SHORT).show()
        } catch (e: XmlPullParserException) {
            e.printStackTrace()
            Toast.makeText(this, "解析文件失败,请确认时候为xlxs格式", Toast.LENGTH_SHORT).show()
        }

        if (str == null) {
            str = "解析文件出现问题"
        }
        return countryList
    }

    fun String.checkMobile(): Boolean {
        val regex = "(\\+\\d+)?1[345789]\\d{9}$"
        return Pattern.matches(regex, this)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {

        return super.onCreateOptionsMenu(menu)
    }


    var isNeedeGroup = false
    val ITEMLENGTH = 50

    override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
        menu?.clear()
        menuInflater.inflate(R.menu.send_action_menu, menu)
        menu?.findItem(R.id.class_action)?.isVisible = false
        if (isNeedeGroup) {
            val i = data.size / ITEMLENGTH
            var v = 0
            if (i > 0) {
                menu?.findItem(R.id.class_action)?.isVisible = false
                v = data.size % ITEMLENGTH
                for (index in 0..i)
                    if (index < i) {
                        menu?.addSubMenu(R.id.cancel_action, index, index * ITEMLENGTH + ITEMLENGTH, "${index * ITEMLENGTH + 1}-${index * ITEMLENGTH + ITEMLENGTH}")
                    } else {
                        if (v > 0) {
                            menu?.addSubMenu(R.id.cancel_action, index, (index) * ITEMLENGTH + v, "${index * ITEMLENGTH + 1}-${index * ITEMLENGTH + v}")
                        }
                    }
            }
        }
        return super.onPrepareOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when (item?.itemId) {
            R.id.send_action -> {
                Observable.create<LinkedList<String>> { sub ->
                    if (data.isEmpty()) {
                        sub.onError(RuntimeException("data is NULL"))
                    } else {
                        sub.onNext(data)
                    }
                    sub.onComplete()
                }.map<String> {
                    val mobile = StringBuffer()
                    for (ind in 0 until it.size) {
                        mobile.append(it[ind]).append(";")
                    }
                    mobile.toString()
                }.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(object : Observer<String> {
                            override fun onNext(t: String) {
                                val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:${t}"))
                                if (isIntentAvailable(this@MainActivity, intent)) {
                                    intent.putExtra("sms_body", "")
                                    startActivity(intent)
                                } else {
                                    toast("没有找到短信编辑器")
                                }
                            }

                            override fun onComplete() {
                                pro.dismiss()
                            }

                            override fun onSubscribe(d: Disposable?) {
                                pro.show()
                            }

                            override fun onError(e: Throwable?) {
                                pro.dismiss()
                                toast("还没有解析联系人")
                            }

                        })

                return true
            }
            R.id.format_action -> {
                if (data.size > 0) {
                    val mobile = StringBuffer()
                    mobile.append("总共${data.size}条记录").append("\n")
                    for (i in 0 until data.size) {
                        if (!isformat) {
                            mobile.append(data[i]).append("\t")
                        } else {
                            mobile.append(data[i]).append("\n")
                            if (i != 0 && (i + 1) % ITEMLENGTH == 0) {
                                mobile.append("======分割线======").append("\n")
                            }
                        }
                    }
                    isformat = !isformat
                    mobile_text.text = mobile.toString()
                } else {
                    toast("还没有解析联系人")
                }
            }
            else -> {
                try {
                    val mobile = StringBuffer()
                    val fromIndex = item!!.itemId * ITEMLENGTH
                    val subList = data.subList(fromIndex, item.order)
                    subList.sort()
                    if (subList != null && subList.isNotEmpty())
                        for (i in 0 until subList.size) {
                            mobile.append(subList[i]).append(";")
                        }
                    val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:${mobile.toString()}"))
                    if (isIntentAvailable(this@MainActivity, intent)) {
                        intent.putExtra("sms_body", "")
                        startActivity(intent)
                    } else {
                        toast("没有找到短信编辑器")
                    }
                    Timber.d(mobile.toString())

                } catch (e: Exception) {
                    Toast.makeText(this, "功能异常，请使用其他功能", Toast.LENGTH_SHORT).show()
                }
            }


        }

        return super.onOptionsItemSelected(item)
    }

    fun toast(string: String) {
        Toast.makeText(this, string, Toast.LENGTH_SHORT).show()
    }

    @SuppressLint("WrongConstant")
    fun isIntentAvailable(context: Context, intent: Intent): Boolean {
        val packageManager = context.getPackageManager();
        val list = packageManager.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES);
        return list.size > 0;
    }


    companion object {
        private const val FILE_SELECT_CODE = 0;
    }
}
